package com.atguigu.tingshu.account.listener;

import com.atguigu.tingshu.account.service.UserAccountService;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @Author GQS @Date 2024/11/3/22:42 @Description
 * 监听账户初始化的消息,完成用户的账户初始化操作
 */
@Component
@Log4j2
public class UserAndAccountMessageListener {
  @Autowired
  private UserAccountService userAccountService;

  /**
   * 完成用户的账户初始化操作
   * @param channel
   * @param message
   */
  @SneakyThrows
  @RabbitListener(queues = "user_and_account_queue")
  public void userAndAccountMessageListenerTask(Channel channel,
                                                Message message){
    //获取消息
    Long userId = Long.valueOf(new String(message.getBody()));
    //获取消息的属性
    MessageProperties messageProperties = message.getMessageProperties();
    //获取消息的编号: 当前消费者消费的第几条消息
    long deliveryTag = messageProperties.getDeliveryTag();
    try {
      //初始化账户
      // int i = 1 / 0; // 出现异常 消息不会确认
      userAccountService.initUserAccount(userId);
      //确认消息: 1.消息的编号 2.是否批量确认
      channel.basicAck(deliveryTag, false);
    }catch (Exception e){
      //消费消息失败,重新消费
      if(messageProperties.getRedelivered()){
        //消息被拒绝过
        log.error("消息两次消费都失败,初始化账户失败的用户id为:" + userId + ",失败的原因为:" + e.getMessage());
        // 第二次失败: 将消息丢掉
        channel.basicReject(deliveryTag, false); // true 会无限将消息放回队列
      }else{
        //消息没有被拒绝过 第一次: 拒绝消息,并将消息放回队列
        channel.basicReject(deliveryTag, true); // 1.消息的编号 2.是否放回队列
      }
    }
    }


  /**
   * 订单支付完成以后记录消费信息
   * @param channel
   * @param message
   */
  @RabbitListener(queues = "order_paid_account_queue")
  @SneakyThrows
  public void orderPaidMessageListener(Channel channel, Message message){
    //获取消息
    String orderNo = new String(message.getBody());
    //获取消息的属性
    MessageProperties messageProperties = message.getMessageProperties();
    //获取消息的编号: 当前消费者消费的第几条消息
    long deliveryTag = messageProperties.getDeliveryTag();
    try {
      //记录消费
      userAccountService.insertUserAccountDetail(orderNo);
      //确认消息: 1.消息的编号 2.是否批量确认
      channel.basicAck(deliveryTag, false);
    }catch (Exception e){
      //消费消息失败,重新消费
      if(messageProperties.getRedelivered()){
        //将消息丢掉
        channel.basicReject(deliveryTag, false);
      }else{
        //消息没有被拒绝过,第一次: 1.消息的编号 2.是否放回队列
        channel.basicReject(deliveryTag, true);
      }
    }
  }

}
